/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2014 Krzysztof Narkiewicz <krzysztof.narkiewicz@ezaquarii.com>
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 */

%{
	#include <iostream>
	#include <cstdlib>
	#include "scanner.h"
	#include "interpreter.h"
	#include "parser.hpp"
	#include "location.hh"

	using namespace std;

	// Original yyterminate() macro returns int. Since we're using Bison 3 variants
	// as tokens, we must redefine it to change type from `int` to `Parser::semantic_type`
	#define yyterminate() CustomParser::Parser::make_END(CustomParser::location());

	// This will track current scanner location.
	// Action is called when length of the token is known.
	#define YY_USER_ACTION m_driver.increaseLocation(yyleng);
	
	// !!!WARNING!!!
	// Location API is used, but the location is not initialized, 'cause I'm lazy. When making
	// a token with make_{something} method you can pass detailed token location. Current location
	// is accessible with m_driver.location() method. All puzzle elements are there - just
	// pass location value in every action code block below. I'm going to waste more time writing
	// this excuse than putting this boilerplate below...
	//
	// Location class can be found in location.hh and posistion.hh files. It's just a bit too much
	// boilerplate for this small example. Bummer.
%}

%option nodefault
%option noyywrap
%option c++
%option yyclass="Scanner"
%option prefix="CustomParser_"

%%

[ \t\n]                     { }
"struct"                    { return CustomParser::Parser::make_STRUCT_BEGIN(yytext, CustomParser::location()); }
"return"                    { return CustomParser::Parser::make_RETURN(yytext, CustomParser::location()); }
[a-zA-Z_:][a-zA-Z0-9_:]*    { return CustomParser::Parser::make_IDENTIFIER(yytext, CustomParser::location()); }
"\""[a-zA-Z0-9_:]*"\""      { return CustomParser::Parser::make_STRING(yytext, CustomParser::location()); }
[0-9]+\.[0-9]*              { return CustomParser::Parser::make_DOUBLE(yytext, CustomParser::location()); }
[0-9]+                      { return CustomParser::Parser::make_INTEGER(yytext, CustomParser::location()); }
"="                         { return CustomParser::Parser::make_EQUAL(yytext, CustomParser::location()); }
"=="                        { return CustomParser::Parser::make_CEQ(yytext, CustomParser::location()); }
"!="                        { return CustomParser::Parser::make_CNE(yytext, CustomParser::location()); }
"<"                         { return CustomParser::Parser::make_CLT(yytext, CustomParser::location()); }
"<="                        { return CustomParser::Parser::make_CLE(yytext, CustomParser::location()); }
">"                         { return CustomParser::Parser::make_CGT(yytext, CustomParser::location()); }
">="                        { return CustomParser::Parser::make_CGE(yytext, CustomParser::location()); }
"("                         { return CustomParser::Parser::make_LPAREN(yytext, CustomParser::location()); }
")"                         { return CustomParser::Parser::make_RPAREN(yytext, CustomParser::location()); }
"{"                         { return CustomParser::Parser::make_LBRACE(yytext, CustomParser::location()); }
"}"                         { return CustomParser::Parser::make_RBRACE(yytext, CustomParser::location()); }
"."                         { return CustomParser::Parser::make_DOT(yytext, CustomParser::location()); }
","                         { return CustomParser::Parser::make_COMMA(yytext, CustomParser::location()); }
"+"                         { return CustomParser::Parser::make_PLUS(yytext, CustomParser::location()); }
"-"                         { return CustomParser::Parser::make_MINUS(yytext, CustomParser::location()); }
"*"                         { return CustomParser::Parser::make_MUL(yytext, CustomParser::location()); }
"/"                         { return CustomParser::Parser::make_DIV(yytext, CustomParser::location()); }
";"                         { return CustomParser::Parser::make_SEMICOLON(yytext, CustomParser::location()); }   
"//".*                      { }     
"/*".*"*/"                  { }
.                           { }          
<<EOF>>                     { return yyterminate(); }


%%

